/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.business.fee.core.service.processor.check;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson2.JSON;
import info.peigen.hotpot.business.fee.core.domain.FeeContext;
import info.peigen.hotpot.business.fee.core.service.processor.base.AbstractFeeServiceProcessor;
import info.peigen.hotpot.business.fee.facade.command.order.rule.FeeRuleBaseOrder;
import info.peigen.hotpot.business.fee.facade.command.order.rule.FeeRuleCreateOrder;
import info.peigen.hotpot.business.fee.facade.command.order.rule.FeeRuleModifyOrder;
import info.peigen.hotpot.business.fee.facade.enums.FeeProductCode;
import info.peigen.hotpot.common.core.order.OrderBase;
import info.peigen.hotpot.common.service.base.exception.BusinessException;
import info.peigen.hotpot.common.service.base.processor.Processor;
import info.peigen.hotpot.common.service.base.processor.ProcessorServiceContext;
import info.peigen.hotpot.common.service.base.time.TimeRange;
import org.noear.solon.annotation.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <b>(CheckTimeRangeOverride24hoursProcessor)</b>
 * 校验时间范围覆盖了24小时
 *
 * @author LiDaHai
 * @version 1.0.0
 * @since 2022/12/14
 */
@Component
public class CheckTimeRangeOverride24hoursProcessor extends AbstractFeeServiceProcessor implements Processor {
    @Override
    public Integer level() {
        return 18;
    }

    @Override
    public void execute(ProcessorServiceContext serviceContext) {
        FeeRuleBaseOrder order = (FeeRuleBaseOrder) serviceContext.getOrder();
        if (order.getCode().isInList(FeeProductCode.Recharge)) {
            String           context     = getContext(serviceContext.getOrder()).replaceAll("24:00", "00:00");
            List<FeeContext> feeContexts = JSON.parseArray(context, FeeContext.class);
            List<TimeRange>  timeRanges  = feeContexts.stream().map(FeeContext::getTimeRange).collect(Collectors.toList());
            Assert.isTrue(isFullDay(timeRanges), () -> new BusinessException("时间段有缺失，未覆盖24小时!"));
        }
    }

    private boolean isFullDay(List<TimeRange> timeRanges) {
        long hours = timeRanges.stream().mapToLong(each -> {
            long hour = each.between(DateUnit.HOUR);
            if (hour < 0) {
                hour = 24 + hour;
            }
            return hour;
        }).sum();
        return hours == 24;
    }

    private String getContext(OrderBase order) {
        if (order instanceof FeeRuleModifyOrder) {
            return ((FeeRuleModifyOrder) order).getContext();
        } else if (order instanceof FeeRuleCreateOrder) {
            return ((FeeRuleCreateOrder) order).getContext();
        } else {
            return null;
        }
    }

}